const fs = require("fs");
const crypto = require("crypto");
const path = require("path");
const dicomParser = require("dicom-parser");
const canvas = require("canvas");
const { getVOILUT } = require('./voiLut')


module.exports = {
  parseToBase64(dicomFileAsBuffer) {
    // let dicomFileAsBuffer = fs.readFileSync(filePath);
    let dataSet = dicomParser.parseDicom(dicomFileAsBuffer)
    let tags = dicomParser.explicitDataSetToJS(dataSet);
    let w = parseInt(tags['x00280011']);   //图片宽度
    let h = parseInt(tags['x00280010']);   //图片高度
    let invert = tags['x00280004'] === 'MONOCHROME1' ? true : false;   //图像是否被反转显示
    let windowCenter = parseInt(tags['x00281050']);   //窗口中心
    let windowWidth = parseInt(tags['x00281051']);   //窗口宽度
    let pixelData = dataSet.elements.x7fe00010;
    let pixelDataBuffer = dicomParser.sharedCopy(dicomFileAsBuffer, pixelData.dataOffset, pixelData.length);
    let cv = canvas.createCanvas(w, h);
    let ctx = cv.getContext('2d', { pixelFormat: 'A8' })    //灰度图
    let uint16 = new Uint16Array(pixelDataBuffer.buffer, pixelDataBuffer.byteOffset, pixelDataBuffer.byteLength / Uint16Array.BYTES_PER_ELEMENT);   //获取uint16的像素数组
    let voiLUT;
    let lut = getLut(uint16, windowWidth, windowCenter, invert, voiLUT); //获取灰度数组
    let uint8 = new Uint8ClampedArray(uint16.length);   //八位灰度像素数组
    //替换对应像素点为灰度
    for (let i = 0, len = uint16.length; i < len; i++) {
      uint8[i] = lut.lutArray[uint16[i]];
    }
    let image = canvas.createImageData(uint8, w, h);
    ctx.putImageData(image, 0, 0);
    let base64 = cv.toDataURL('image/png');
    return base64
  },
};

const getLut = (data, windowWidth, windowCenter, invert, voiLUT) => {
  let minPixelValue = 0;
  let maxPixelValue = 0;
  for (let i = 0, len = data.length; i < len; i++) {
    if (minPixelValue > data[i]) {
      minPixelValue = data[i];
    }
    if (maxPixelValue < data[i]) {
      maxPixelValue = data[i];
    }
  }
  let offset = Math.min(minPixelValue, 0);
  let lutArray = new Uint8ClampedArray(maxPixelValue - offset + 1);
  const vlutfn = getVOILUT(windowWidth, windowCenter, voiLUT, true);
  if (invert === true) {
    for (let storedValue = minPixelValue; storedValue <= maxPixelValue; storedValue++) {
      lutArray[storedValue + (-offset)] = 255 - vlutfn(storedValue);
    }
  } else {
    for (let storedValue = minPixelValue; storedValue <= maxPixelValue; storedValue++) {
      lutArray[storedValue + (-offset)] = vlutfn(storedValue);
    }
  }
  return {
    minPixelValue: minPixelValue,
    maxPixelValue: maxPixelValue,
    lutArray: lutArray,
  };
}
